﻿import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import kliment.events.Event;
import mx.utils.Delegate;

import kliment.display.loader.MCLoader;
import kliment.utils.TransformCalc;
import kliment.display.MCC;
import kliment.math.Calc;
/**
 * ...
 * @author	Kliment
 * @version	3.6.5
 */

class kliment.display.loader.ImageLoader extends MCLoader {
	public static var MIN_WIDTH:Number = 1;
	public static var MIN_HEIGHT:Number = 1;
	public static var MAX_WIDTH:Number = 2880;
	public static var MAX_HEIGHT:Number = 2880;
	private var _width:Number;
	private var _height:Number;
	private var _caching:Boolean;
	private var _crop:Boolean;
	private var _centred:Boolean;
	private var _cut:Boolean;
	private var _bodyBMP:BitmapData;
	private var _resultBMP:BitmapData;
	private var _smoothing:Boolean = false;
	private var _content_mc:MovieClip;
	public var minWidth:Number = 1;
	public var minHeight:Number = 1;
	public var increase:Boolean = true;	
	
	public function ImageLoader(target_mc:MovieClip, width:Number, height:Number, smoothing:Boolean) {
		super(target_mc);
		_smoothing = smoothing || false;
		_width = Calc.inInterval(MIN_WIDTH, MAX_WIDTH, Math.round(width)) || MIN_WIDTH;
		_height = Calc.inInterval(MIN_HEIGHT, MAX_HEIGHT, Math.round(height)) || MIN_HEIGHT;
	}
	
	public function load(url:String, caching:Boolean, crop:Boolean, centred:Boolean, cut:Boolean):Boolean {
		_caching = caching;
		_crop = crop;
		_centred = centred;
		_cut = cut;
		_content_mc = _target_mc;
		_target_mc = MCC.create(_content_mc);
		return super.load(url);
	}
	
	public static function resizeBitmap(target:BitmapData, width:Number, height:Number, crop:Boolean, centred:Boolean, cut:Boolean):BitmapData {
		var resizeM:Matrix = _getResizeMatrix(target, width, height, crop, centred);
		if (cut && !centred) {
			width = Math.min(width, resizeM.a * target.width);
			height = Math.min(height, resizeM.d * target.height);
		}
		var result:BitmapData = new BitmapData(width, height, true, 0x000000);
		
		result.draw(target, resizeM, null, null, null, true);
		return result;
	}
	
	public function resizeThis(width:Number, height:Number):Boolean {
		if (!_caching) return false;
		_resultBMP = resizeBitmap(_bodyBMP, width, height, _crop, _centred, _cut)
		MCC.clear(_target_mc);
		MCC.attachBitmap(_target_mc, _resultBMP, 'auto', _smoothing);
		return true;
	}
	
	private function _createImage(crop:Boolean, centred:Boolean, cut:Boolean):Void {
		_bodyBMP = new BitmapData(_target_mc._width, _target_mc._height, true, 0x000000);
		_bodyBMP.draw(_target_mc);
		var newWidth:Number;
		var newHeight:Number;
		
		if (increase == true) {
			newWidth = Math.max(_width, minWidth);
			newHeight = Math.max(_height, minHeight);
		} else {
			newWidth = Math.min(_width, _bodyBMP.width);
			newHeight = Math.min(_height, _bodyBMP.height);
		}
		
		_resultBMP = resizeBitmap(_bodyBMP, newWidth, newHeight, crop, centred, cut)
		_mcLoader.unloadClip();
		MCC.clear(_content_mc);
		_target_mc = _content_mc;
		if (!_caching) {
			_bodyBMP.dispose();
			delete _bodyBMP;
		}
		
		var cell_mc:MovieClip = MCC.create(_target_mc);
		cell_mc._visible = false;
		cell_mc.attachBitmap(_resultBMP, 0, 'auto', _smoothing);
		
		cell_mc._visible = true;
	}
	
	public function setMinSize(width:Number, height:Number):Void {
		minWidth = width;
		minHeight = height;
	}
	
	static private function _getResizeMatrix(target:BitmapData, width:Number, height:Number, cropp:Boolean, centred:Boolean):Matrix {
		var rectangle:Rectangle = TransformCalc.putInSpace(target, width, height, cropp, centred);
		return new Matrix(rectangle.width/target.width, 0, 0, rectangle.height/target.height, rectangle.x, rectangle.y);
	}
	
	public function get originalBitmap():BitmapData {
		return _bodyBMP;
	}
	
	public function get finalBitmap():BitmapData {
		return _resultBMP;
	}
	
	private function _onLoadInitHandler(target_mc:MovieClip):Void {
		target_mc._visible = false;
		_createImage(_crop, _centred, _cut);
		super._onLoadInitHandler(target_mc);
	}
	
	public function clear():Void {
		_resultBMP.dispose();
		_bodyBMP.dispose();
		_resultBMP = null;
		_bodyBMP = null;
		MCC.clear(_target_mc);
	}
	
	public function toString():String {
		return "[ImageLoader target_mc=" + _target_mc + "]";
	}
	
	public function remove():Void {
		clear();
		super.remove();
	}
}